package fantasy;

import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

public class SaveSingleStandingServlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static XPath xPath = XPATH.get().newXPath();
	
	private YahooParseXml yahooParser = new YahooParseXml();


	protected void service(HttpServletRequest req, HttpServletResponse resp)
	throws ServletException, IOException {

		PersistenceManager pm = PMF.get().getPersistenceManager();
		
		String userkey = req.getParameter("user");
		
		Integer lnum = Integer.parseInt(req.getParameter("league"));
		
		if(userkey != null) {
			log("Found User Key: " + userkey);
			try {
				yahooParser.getXmlFromDS(userkey);
				NodeList nodes = yahooParser.getXmlNodes("//league");
				yahooParser.parseForStatics(nodes.item(lnum));
				saveStandings(nodes.item(lnum));
			} catch (XPathExpressionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private void saveStandings(Node leagueNode) 
	  throws IOException, NumberFormatException, XPathExpressionException {


		//XPathFactory factory = XPathFactory.newInstance();

		//XPath xPath= XPATH.get().newXPath();

		
		String score_type = (String)xPath.evaluate("settings/scoring_type", leagueNode, XPathConstants.STRING);
		

		if(!score_type.equals("roto")) {
			log("This is not a roto league");
			return;
		}
		/*
		// Game Key Finder
		
		String league_key = (String)xPath.evaluate("league_key", leagueNode, XPathConstants.STRING);
		String regex = "\\.";
		Pattern numSplit = Pattern.compile(regex);
		String[] m = numSplit.split(league_key);
		Integer game_key = Integer.parseInt(m[0]);
		String game_type = "unknown";
		if(game_key.equals(238)) {
			game_type = "baseball";
		}

		*/
		String league_update_timestamp = (String)xPath.evaluate("league_update_timestamp", leagueNode, XPathConstants.STRING);

		NodeList teamNodes = (NodeList)xPath.evaluate("standings/teams/team", leagueNode, XPathConstants.NODESET);
		int nodeTeamCount = teamNodes.getLength();
		log("Team Node Count: " + nodeTeamCount);
		//iterate over search Result nodes
		PersistenceManager pm = PMF.get().getPersistenceManager();

		// Compile XPath expressions to make the script go faster
		XPathExpression xpath_team_key = xPath.compile("team_key");
		XPathExpression xpath_stats = xPath.compile("team_stats/stats/stat");
		
		for (int i = 0; i < nodeTeamCount; i++) {

	  	  String team_key = (String)xpath_team_key.evaluate(teamNodes.item(i), XPathConstants.STRING);
		  LeagueStandings ls = new LeagueStandings();
		  
		  log(yahooParser.getLeague_key());
		  
  		  String standing_entry_key = team_key + "-" + league_update_timestamp;
		  Key stkey = new KeyFactory.Builder(LeagueSettings.class.getSimpleName(),yahooParser.getLeague_key())
		  	.addChild(LeagueTeams.class.getSimpleName(),team_key)
	  		.addChild(LeagueStandings.class.getSimpleName(), standing_entry_key)
	  		.getKey();
		  
		  Transaction tx = pm.currentTransaction();

		  try{
			  tx.begin();
			
  			  ls = pm.getObjectById(LeagueStandings.class, stkey);
			  tx.commit();
			  log("A LeagueStanding already exists for " + stkey.toString());
		  }  catch (JDOObjectNotFoundException e) {
			  log("LeagueStanding didn't exists so a new one is being created");
  			  NodeList statsNodes = (NodeList)xpath_stats.evaluate(teamNodes.item(i), XPathConstants.NODESET);
			  int nodeStatsCount = statsNodes.getLength();
			  Set<TeamStats> stats = new HashSet<TeamStats>();
			  for (int k = 0; k < nodeStatsCount; k++) {
				  
				  TeamStats s = yahooParser.parseLeagueForTeamStats(statsNodes.item(k));
				  
				  log(s.getStatid().toString());
				  
				  String single_stat_key_string = team_key + league_update_timestamp + s.getStatid().toString();
				  Key single_stat_key = KeyFactory.createKey(TeamStats.class.getSimpleName(), single_stat_key_string);
				  
				  s.setKey(single_stat_key);
				  stats.add(s);
				  
			  }
		  	  ls = yahooParser.parseLeagueForStandings(teamNodes.item(i));
		  	  ls.setTeamkeystamp(stkey);
		  	  ls.setStats(stats);
			  pm.makePersistentAll(ls);
			  tx.commit();
	  	  } finally {
	          if (tx.isActive()) {
	              tx.rollback();
	          }
		  }
		}
        pm.close();
	}

}
